/**
 * PowerUp - 道具基类
 * 实现道具的基础功能，包括生成、收集和效果应用机制
 */

import { Entity, EntityType, type EntityOptions } from './Entity'
import type { Player } from './Player'
import type { Vector2D } from './GameEngine'

/**
 * 道具类型枚举
 */
export enum PowerUpType {
  MAGNET = 'magnet',           // 磁铁 - 自动吸引金币
  SPEED_BOOST = 'speedBoost',  // 加速 - 提高移动速度
  SHIELD = 'shield',           // 护盾 - 免疫一次伤害
  DOUBLE_SCORE = 'doubleScore', // 双倍分数 - 分数翻倍
  EXTRA_LIFE = 'extraLife',    // 额外生命 - 增加生命值
  JUMP_BOOST = 'jumpBoost',    // 跳跃增强 - 提高跳跃力
  SLOW_TIME = 'slowTime'       // 时间减缓 - 减慢游戏速度
}

/**
 * 道具稀有度枚举
 */
export enum PowerUpRarity {
  COMMON = 'common',       // 普通 - 70%
  RARE = 'rare',          // 稀有 - 20%
  EPIC = 'epic',          // 史诗 - 8%
  LEGENDARY = 'legendary'  // 传说 - 2%
}

/**
 * 道具效果接口
 */
export interface PowerUpEffect {
  /**
   * 应用效果到玩家
   * @param player - 目标玩家
   */
  apply(player: Player): void

  /**
   * 移除效果从玩家
   * @param player - 目标玩家
   */
  remove(player: Player): void

  /**
   * 更新效果（每帧调用）
   * @param player - 目标玩家
   * @param deltaTime - 时间差
   */
  update?(player: Player, deltaTime: number): void
}

/**
 * 道具配置接口
 */
export interface PowerUpConfig {
  type: PowerUpType
  duration: number        // 持续时间（毫秒），0表示永久或瞬时效果
  value: number          // 效果强度值
  rarity: PowerUpRarity
  stackable: boolean     // 是否可以叠加
  maxStacks?: number     // 最大叠加数量
  description: string    // 道具描述
  iconColor: string      // 图标颜色
}

/**
 * 道具选项接口
 */
export interface PowerUpOptions extends Omit<EntityOptions, 'type'> {
  powerUpType: PowerUpType
  config?: Partial<PowerUpConfig>
  effect?: PowerUpEffect
}

/**
 * 活跃道具状态接口
 */
export interface ActivePowerUp {
  type: PowerUpType
  effect: PowerUpEffect
  remainingTime: number
  stacks: number
  config: PowerUpConfig
}

/**
 * PowerUp基类
 * 所有道具的基础实现
 */
export abstract class PowerUp extends Entity {
  public readonly powerUpType: PowerUpType
  public readonly config: PowerUpConfig
  public readonly effect: PowerUpEffect
  public collected: boolean = false
  public collectTime: number = 0

  // 动画属性
  private floatOffset: number = 0
  private floatSpeed: number = 2 // 浮动速度
  private floatAmplitude: number = 10 // 浮动幅度
  private rotationAngle: number = 0
  private rotationSpeed: number = 1 // 旋转速度

  constructor(options: PowerUpOptions) {
    super({
      ...options,
      type: EntityType.POWERUP
    })

    this.powerUpType = options.powerUpType
    this.config = this.createConfig(options.config)
    this.effect = options.effect || this.createDefaultEffect()

    // 设置默认大小
    if (!options.width) this.width = 32
    if (!options.height) this.height = 32

    // 初始化浮动动画的随机偏移
    this.floatOffset = Math.random() * Math.PI * 2
  }

  /**
   * 更新道具逻辑
   */
  update(deltaTime: number): void {
    if (!this.active || this.collected) {
      return
    }

    // 应用基础物理（向左移动）
    this.applyPhysics(deltaTime)

    // 更新浮动动画
    this.updateFloatAnimation(deltaTime)

    // 检查是否超出屏幕边界
    if (this.x + this.width < -50) {
      this.destroy()
    }
  }

  /**
   * 渲染道具
   */
  render(ctx: CanvasRenderingContext2D): void {
    if (!this.visible || this.collected) return

    ctx.save()

    // 应用旋转和浮动效果
    const centerX = this.x + this.width / 2
    const centerY = this.y + this.height / 2

    ctx.translate(centerX, centerY)
    ctx.rotate(this.rotationAngle)

    // 绘制道具
    if (this.sprite && this.sprite.image) {
      ctx.drawImage(
        this.sprite.image,
        -this.width / 2,
        -this.height / 2,
        this.width,
        this.height
      )
    } else {
      this.renderDefault(ctx)
    }

    // 绘制稀有度光环
    this.renderRarityAura(ctx)

    ctx.restore()

    // 绘制道具信息（调试用）
    if (process.env.NODE_ENV === 'development') {
      this.renderDebugInfo(ctx)
    }
  }

  /**
   * 收集道具
   * @param player - 收集道具的玩家
   * @returns 是否成功收集
   */
  collect(player: Player): boolean {
    if (this.collected || !this.active) {
      return false
    }

    this.collected = true
    this.collectTime = Date.now()
    this.visible = false

    // 应用道具效果
    this.applyEffect(player)

    // 更新玩家统计
    player.stats.powerUpsCollected++

    return true
  }

  /**
   * 应用道具效果到玩家
   */
  protected applyEffect(player: Player): void {
    this.effect.apply(player)
  }

  /**
   * 获取道具信息
   */
  getInfo(): {
    type: PowerUpType
    config: PowerUpConfig
    collected: boolean
    position: Vector2D
  } {
    return {
      type: this.powerUpType,
      config: this.config,
      collected: this.collected,
      position: { x: this.x, y: this.y }
    }
  }

  /**
   * 创建道具配置
   */
  protected abstract createConfig(customConfig?: Partial<PowerUpConfig>): PowerUpConfig

  /**
   * 创建默认效果
   */
  protected abstract createDefaultEffect(): PowerUpEffect

  /**
   * 更新浮动动画
   */
  private updateFloatAnimation(deltaTime: number): void {
    const deltaSeconds = deltaTime / 1000

    // 更新浮动偏移
    this.floatOffset += this.floatSpeed * deltaSeconds
    const floatY = Math.sin(this.floatOffset) * this.floatAmplitude

    // 应用浮动效果（修改渲染位置，不影响碰撞检测）
    this.y += floatY * 0.1 // 轻微的浮动效果

    // 更新旋转
    this.rotationAngle += this.rotationSpeed * deltaSeconds
    if (this.rotationAngle > Math.PI * 2) {
      this.rotationAngle -= Math.PI * 2
    }
  }

  /**
   * 渲染默认外观
   */
  protected renderDefault(ctx: CanvasRenderingContext2D): void {
    // 绘制道具主体
    ctx.fillStyle = this.config.iconColor
    ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height)

    // 绘制边框
    ctx.strokeStyle = '#FFFFFF'
    ctx.lineWidth = 2
    ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height)

    // 绘制道具类型标识
    ctx.fillStyle = '#FFFFFF'
    ctx.font = '12px Arial'
    ctx.textAlign = 'center'
    ctx.textBaseline = 'middle'
    
    const typeText = this.getTypeSymbol()
    ctx.fillText(typeText, 0, 0)
  }

  /**
   * 渲染稀有度光环
   */
  private renderRarityAura(ctx: CanvasRenderingContext2D): void {
    const auraColors = {
      [PowerUpRarity.COMMON]: '#FFFFFF',
      [PowerUpRarity.RARE]: '#00FF00',
      [PowerUpRarity.EPIC]: '#0080FF',
      [PowerUpRarity.LEGENDARY]: '#FF8000'
    }

    const auraColor = auraColors[this.config.rarity]
    if (!auraColor || this.config.rarity === PowerUpRarity.COMMON) {
      return
    }

    // 绘制光环效果
    const gradient = ctx.createRadialGradient(0, 0, this.width / 2, 0, 0, this.width)
    gradient.addColorStop(0, 'transparent')
    gradient.addColorStop(0.7, 'transparent')
    gradient.addColorStop(1, auraColor + '40') // 40% 透明度

    ctx.fillStyle = gradient
    ctx.fillRect(-this.width, -this.height, this.width * 2, this.height * 2)
  }

  /**
   * 渲染调试信息
   */
  private renderDebugInfo(ctx: CanvasRenderingContext2D): void {
    ctx.fillStyle = '#000000'
    ctx.font = '10px Arial'
    ctx.textAlign = 'left'
    ctx.textBaseline = 'top'
    
    const debugText = `${this.powerUpType} (${this.config.rarity})`
    ctx.fillText(debugText, this.x, this.y - 15)
  }

  /**
   * 获取道具类型符号
   */
  private getTypeSymbol(): string {
    const symbols = {
      [PowerUpType.MAGNET]: 'M',
      [PowerUpType.SPEED_BOOST]: 'S',
      [PowerUpType.SHIELD]: 'D',
      [PowerUpType.DOUBLE_SCORE]: '2',
      [PowerUpType.EXTRA_LIFE]: '+',
      [PowerUpType.JUMP_BOOST]: 'J',
      [PowerUpType.SLOW_TIME]: 'T'
    }
    return symbols[this.powerUpType] || '?'
  }

  /**
   * 获取默认颜色
   */
  protected getDefaultColor(): string {
    return this.config.iconColor
  }
}

/**
 * PowerUp管理器
 * 管理所有活跃的道具效果
 */
export class PowerUpManager {
  private activePowerUps: Map<PowerUpType, ActivePowerUp> = new Map()
  private player: Player | null = null

  /**
   * 设置目标玩家
   */
  setPlayer(player: Player): void {
    this.player = player
  }

  /**
   * 添加道具效果
   */
  addPowerUp(powerUp: PowerUp): boolean {
    if (!this.player) {
      console.warn('PowerUpManager: No player set')
      return false
    }

    const type = powerUp.powerUpType
    const config = powerUp.config
    const effect = powerUp.effect

    // 检查是否已存在该类型的道具
    const existing = this.activePowerUps.get(type)
    
    if (existing) {
      if (config.stackable && existing.stacks < (config.maxStacks || 1)) {
        // 可以叠加
        existing.stacks++
        existing.remainingTime = Math.max(existing.remainingTime, config.duration)
        return true
      } else if (!config.stackable) {
        // 不可叠加，刷新持续时间
        existing.remainingTime = config.duration
        return true
      } else {
        // 已达到最大叠加数
        return false
      }
    }

    // 添加新的道具效果
    const activePowerUp: ActivePowerUp = {
      type,
      effect,
      remainingTime: config.duration,
      stacks: 1,
      config
    }

    this.activePowerUps.set(type, activePowerUp)
    effect.apply(this.player)

    return true
  }

  /**
   * 移除道具效果
   */
  removePowerUp(type: PowerUpType): boolean {
    const powerUp = this.activePowerUps.get(type)
    if (!powerUp || !this.player) {
      return false
    }

    powerUp.effect.remove(this.player)
    this.activePowerUps.delete(type)
    return true
  }

  /**
   * 更新所有道具效果
   */
  update(deltaTime: number): void {
    if (!this.player) return

    const toRemove: PowerUpType[] = []

    for (const [type, powerUp] of this.activePowerUps) {
      // 更新持续时间
      if (powerUp.remainingTime > 0) {
        powerUp.remainingTime -= deltaTime
        
        if (powerUp.remainingTime <= 0) {
          toRemove.push(type)
        }
      }

      // 更新效果
      if (powerUp.effect.update) {
        powerUp.effect.update(this.player, deltaTime)
      }
    }

    // 移除过期的道具效果
    toRemove.forEach(type => this.removePowerUp(type))
  }

  /**
   * 获取所有活跃道具
   */
  getActivePowerUps(): ActivePowerUp[] {
    return Array.from(this.activePowerUps.values())
  }

  /**
   * 检查是否有特定类型的道具
   */
  hasPowerUp(type: PowerUpType): boolean {
    return this.activePowerUps.has(type)
  }

  /**
   * 获取特定道具的剩余时间
   */
  getRemainingTime(type: PowerUpType): number {
    const powerUp = this.activePowerUps.get(type)
    return powerUp ? powerUp.remainingTime : 0
  }

  /**
   * 获取特定道具的叠加数量
   */
  getStacks(type: PowerUpType): number {
    const powerUp = this.activePowerUps.get(type)
    return powerUp ? powerUp.stacks : 0
  }

  /**
   * 清除所有道具效果
   */
  clearAll(): void {
    if (!this.player) return

    for (const [, powerUp] of this.activePowerUps) {
      powerUp.effect.remove(this.player)
    }

    this.activePowerUps.clear()
  }

  /**
   * 获取道具管理器状态信息
   */
  getStatus(): {
    activeCount: number
    powerUps: { type: PowerUpType; remainingTime: number; stacks: number }[]
  } {
    return {
      activeCount: this.activePowerUps.size,
      powerUps: Array.from(this.activePowerUps.values()).map(powerUp => ({
        type: powerUp.type,
        remainingTime: powerUp.remainingTime,
        stacks: powerUp.stacks
      }))
    }
  }
}